﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using  MyBasicLib.Extensions;
using RUC.Core.Entities;
using MyBasicLib.Collections.Generic;

namespace MyBasicLib.Test.Extensions
{  
    /// <summary>
    ///This is a test class for ITreeNodeExtensionTest and is intended
    ///to contain all ITreeNodeExtensionTest Unit Tests
    ///</summary>
    [TestClass()]
    public class ITreeNodeExtensionTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion
        private static List<T> GetList<T>() where T : ITreeNode, new()
        {
            List<T> list = new List<T>() { 
                new T() { Id = "0" },
                new T() { Id = "1",ParentId="0" },
                new T() { Id = "2",ParentId="1" } ,
                new T() { Id = "3",ParentId="2" } ,
                new T() { Id = "4",ParentId="3" } , 
                new T() { Id = "5",ParentId="3" }  };
            return list;
        }
        #region GetRootNodeList
         
        public void GetRootNodeListTest0Helper<T>() where T : ITreeNode
        {
            List<T> list = null;
            list.GetRootNodeList();
        }
        /// <summary>
        /// list can not be null
        /// </summary>
        [TestMethod]
        [ExpectedExceptionAttribute(typeof(ArgumentNullException))]
        public void GetRootNodeListTest_list_can_not_be_null()
        {
            GetRootNodeListTest0Helper<Organization>();
        } 


        public void GetRootNodeListTest1Helper<T>() where T : ITreeNode
        {
            List<T> list = new List<T>();
            Assert.AreEqual(list.GetRootNodeList().Count(), 0);
            Assert.AreEqual(list.GetRootNodeList().FirstOrDefault(), null);
        }
        /// <summary>
        /// empty list will return null
        /// </summary>
        [TestMethod]
        public void GetRootNodeListTest_empty_list_will_return_null () 
        {
            GetRootNodeListTest1Helper<Organization>();
        }

         
        public void GetRootNodeListTest2Helper<T>() where T : ITreeNode, new()
        {
            List<T> list = new List<T>() { new T() { Id = "1" } };
            Assert.AreEqual(list.GetRootNodeList().Count(), 1);
            Assert.AreEqual(list.GetRootNodeList().Single().Id, "1");
        }
        /// <summary>
        /// single list 
        /// </summary>
        [TestMethod]
        public void GetRootNodeListTest_single_list()  
        {
            GetRootNodeListTest2Helper<Organization>();        
        }
         
 
        public void GetRootNodeListTest10Helper<T>() where T : ITreeNode, new()
        {
            var list = Enumerable.Range(0, 10).Select(i => new T() { Id = i.ToString() });
            Assert.AreEqual(list.GetRootNodeList().Count(), 10);
        } 
        /// <summary>
        /// all root
        /// </summary>
        [TestMethod]
        public void GetRootNodeListTest_all_root()  
        {
            GetRootNodeListTest10Helper<Organization>();     
        
        
        }
        #endregion

        #region GetNodeById
        public void GetNodeByIdTest0Helper<T>(List<T> list,string id) where T : ITreeNode
        { 
            list.GetNodeById(id);
        }

        [TestMethod]
        [ExpectedExceptionAttribute(typeof(ArgumentNullException))]
        public void GetNodeByIdTest_list_cannot_be_null()
        {
            GetNodeByIdTest0Helper<Organization>(null, "2");
        } 
        [TestMethod]
        [ExpectedExceptionAttribute(typeof(ArgumentException))]
        public void GetNodeByIdTest_id_cannot_be_null()
        {
            GetNodeByIdTest0Helper<Organization>(new List<Organization>(), null);

        }
        [TestMethod]
        [ExpectedExceptionAttribute(typeof(ArgumentException))]
        public void GetNodeByIdTest_id_cannot_be_empty()
        {
            GetNodeByIdTest0Helper<Organization>(new List<Organization>(), "");
        }
        public void GetNodeByIdTest1Helper<T>(string id)
            where T : ITreeNode, new()
        {
            var list = Enumerable.Range(0, 10).Select(i => new T() { Id = i.ToString() });// TODO: Initialize to an appropriate value

            // TODO: Initialize to an appropriate value
            T expected = new T() { Id = id }; // TODO: Initialize to an appropriate value
            T actual;
            actual = ITreeNodeExtension.GetNodeById<T>(list, id);
            Assert.AreEqual(expected.Id, actual.Id);
        }
        [TestMethod()]
        public void GetNodeByIdTest_middle()
        {
            GetNodeByIdTest1Helper<Organization>("3");
        } 
        [TestMethod()]
        public void GetNodeByIdTest_first()
        {
            GetNodeByIdTest1Helper<Organization>("0"); 
        } 

        [TestMethod()]
        public void GetNodeByIdTest_last()
        {
            GetNodeByIdTest1Helper<Organization>("9");

        }
        public void GetNodeByIdTest2Helper<T>(string id)
        where T : ITreeNode, new()
        {
            var list = Enumerable.Range(0, 10).Select(i => new T() { Id = i.ToString()+"A" });// TODO: Initialize to an appropriate value

            //string id = "10"; // TODO: Initialize to an appropriate value
            T expected = default(T); // TODO: Initialize to an appropriate value
            T actual;
            actual = ITreeNodeExtension.GetNodeById<T>(list, id);
            Assert.AreEqual(expected, actual);
        } 
        [TestMethod()]
        public void GetNodeByIdTest_not_exist()
        {
            GetNodeByIdTest2Helper<Organization>("10A");
        } 

        [TestMethod()]
        public void GetNodeByIdTest_case_sensitive()
        {
            GetNodeByIdTest2Helper<Organization>("10a");
        } 
        #endregion

        #region GetAllChildNodes

        public void GetAllChildNodesTest0Helper<T>(List<T> list, string id) where T : ITreeNode
        {
            list.GetAllChildNodes(id);
        }

        [TestMethod]
        [ExpectedExceptionAttribute(typeof(ArgumentNullException))]
        public void GetAllChildNodes_list_cannot_be_null()
        {
            GetAllChildNodesTest0Helper<Organization>(null, "2");
        }
        [TestMethod]
        [ExpectedExceptionAttribute(typeof(ArgumentException))]
        public void GetAllChildNodes_id_cannot_be_null()
        {
            GetAllChildNodesTest0Helper<Organization>(new List<Organization>(), null);

        }
        [TestMethod]
        [ExpectedExceptionAttribute(typeof(ArgumentException))]
        public void GetAllChildNodes_id_cannot_be_empty()
        {
            GetAllChildNodesTest0Helper<Organization>(new List<Organization>(), "");
        }


        /// <summary>
        ///A test for GetAllChildNodes
        ///</summary>
        public void GetAllChildNodesTestHelper<T>(string id,int count,bool includeSelf=false )
            where T : ITreeNode, new()
        {
            List<T> list = GetList<T>();
            // IEnumerable<T> expected = null; // TODO: Initialize to an appropriate value
            IEnumerable<T> actual;
            actual = ITreeNodeExtension.GetAllChildNodes<T>(list, id, includeSelf);
            Assert.AreEqual(count, actual.Count());
        }

        [TestMethod()]
        public void GetAllChildNodesTest_first()
        {
            GetAllChildNodesTestHelper<Organization>("0",5);
        }
        [TestMethod()]
        public void GetAllChildNodesTest_mid()
        {
            GetAllChildNodesTestHelper<Organization>("2", 3);
        }
        [TestMethod()]
        public void GetAllChildNodesTest_last()
        {
            GetAllChildNodesTestHelper<Organization>("5", 0);
        } 
        [TestMethod()]
        public void GetAllChildNodesTest_node_not_exsit()
        {
            GetAllChildNodesTestHelper<Organization>("10", 0);
        }
        [TestMethod()]
        public void GetAllChildNodesTest_include_self()
        {
            GetAllChildNodesTestHelper<Organization>("2", 4 ,true);
        }
        [TestMethod()]
        public void GetAllChildNodesTest_include_self_node_not_exsit()
        {
            GetAllChildNodesTestHelper<Organization>("10", 0);
        }
        #endregion

        #region GetAllParentNodes
        /// <summary>
        ///A test for GetAllParentNodes
        ///</summary>
        public void GetAllParentNodesTestHelper<T>(string id,int count)
            where T : ITreeNode,new()
        {
            List<T> list = GetList<T>();
            // IEnumerable<T> expected = null; // TODO: Initialize to an appropriate value
            IEnumerable<T> actual;
            actual = ITreeNodeExtension.GetAllParentNodes<T>(list, id);
            Assert.AreEqual(count, actual.Count());
        }

        [TestMethod()]
        public void GetAllParentNodesTest_first() 
        {
            GetAllParentNodesTestHelper<Organization>("0", 0);
        } 
        [TestMethod()]
        public void GetAllParentNodesTest_mid() 
        {
            GetAllParentNodesTestHelper<Organization>("3", 3);
        }  
        [TestMethod()]
        public void GetAllParentNodesTest_last() 
        {
            GetAllParentNodesTestHelper<Organization>("5", 4);
        }
        [TestMethod()]
        public void GetAllParentNodesTest_not_exsit()
        {
            GetAllParentNodesTestHelper<Organization>("6", 0);
        } 
        #endregion
 

        /// <summary>
        ///A test for GetNodeDeep
        ///</summary>
        public void GetNodeDeepTestHelper<T>(string id,int deep)
            where T : ITreeNode,new()
        {
            IEnumerable<T> list = GetList<T>(); // TODO: Initialize to an appropriate value
            //string id = string.Empty; // TODO: Initialize to an appropriate value
            int expected = deep; // TODO: Initialize to an appropriate value
            int actual;
            actual = ITreeNodeExtension.GetNodeDeep<T>(list, id);
            Assert.AreEqual(expected, actual);
           // Assert.Inconclusive("Verify the correctness of this test method.");
        }

        [TestMethod()]
        public void GetNodeDeepTest()
        {
            GetNodeDeepTestHelper<Organization>("0", 0);
            GetNodeDeepTestHelper<Organization>("1", 1);
            GetNodeDeepTestHelper<Organization>("3", 3);
            GetNodeDeepTestHelper<Organization>("5", 4);
            GetNodeDeepTestHelper<Organization>("6", -1);
        }

        #region GetNodesByParentId
        /// <summary>
        ///A test for GetNodesByParentId
        ///</summary>
        public void GetNodesByParentIdTestHelper<T>(string  id,int count )
            where T : ITreeNode,new()
        {
            List<T> list = GetList<T>();
           // string id = string.Empty; // TODO: Initialize to an appropriate value
           // IEnumerable<T> expected = null; // TODO: Initialize to an appropriate value
            IEnumerable<T> actual;
            actual = ITreeNodeExtension.GetNodesByParentId<T>(list, id);
            Assert.AreEqual(count, actual.Count()); 
        }

        [TestMethod()]
        public void GetNodesByParentIdTest()
        {
            GetNodesByParentIdTestHelper<Organization>("0", 1);
            GetNodesByParentIdTestHelper<Organization>("3", 2);
            GetNodesByParentIdTestHelper<Organization>("5", 0);
            GetNodesByParentIdTestHelper<Organization>("6", 0);
        }
        
        #endregion
        #region GetParentNode
        /// <summary>
        ///A test for GetParentNode
        ///</summary>
        public void GetParentNodeTestHelper<T>(string id,string pid)
            where T : class, ITreeNode,new()
        {
            List<T> list = GetList<T>();
            // string id = string.Empty; // TODO: Initialize to an appropriate value
            // T expected =; // TODO: Initialize to an appropriate value
            T actual;
            actual = ITreeNodeExtension.GetParentNode<T>(list, id) ?? new T();
            Assert.AreEqual(pid, actual.Id);
        }

        [TestMethod()]
        public void GetParentNodeTest_first()
        {
            GetParentNodeTestHelper<Organization>("0", null);
        } 
        [TestMethod()]
        public void GetParentNodeTest_mid()
        {
            GetParentNodeTestHelper<Organization>("3", "2");
        }
        [TestMethod()]
        public void GetParentNodeTest_last()
        {
            GetParentNodeTestHelper<Organization>("5", "3");
        }
        [TestMethod()]
        public void GetParentNodeTest_not()
        {
            GetParentNodeTestHelper<Organization>("10", null);
        }
        
        #endregion

     

  

        ///// <summary>
        /////A test for VisitPreorder
        /////</summary>
        //public void VisitPreorderTestHelper<T>()
        //    where T : ITreeNode
        //{
        //    IEnumerable<T> list = null; // TODO: Initialize to an appropriate value
        //    string rootId = string.Empty; // TODO: Initialize to an appropriate value
        //    Action<T> act = null; // TODO: Initialize to an appropriate value
        //    ITreeNodeExtension.VisitPreorder<T>(list, rootId, act);
        //    Assert.Inconclusive("A method that does not return a value cannot be verified.");
        //}

        //[TestMethod()]
        //public void VisitPreorderTest()
        //{
        //    //Assert.Inconclusive("No appropriate type parameter is found to satisfies the type constraint(s) of T. " +
        //    //        "Please call VisitPreorderTestHelper<T>() with appropriate type parameters.");
        //}
    }
}
